from django import forms
from community import models
from community.models import UserInfo
from django.conf import settings
import random
from utils.tencent.sms import send_sms_single
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from django_redis import get_redis_connection


class RegisterModelForm(forms.ModelForm):
    mobile_phone = forms.CharField(label='手机号', validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误！'), ])
    password = forms.CharField(label='密码', min_length=8, max_length=16,
                               error_messages={'min_length': '密码过短!', 'max_length': '密码过长!'},
                               widget=forms.PasswordInput())
    confirm_password = forms.CharField(label='确认密码', min_length=8, max_length=16,
                                       error_messages={'min_length': '密码过短,不能少于8位!', 'max_length': '密码过长,不能超过16位!'},
                                       widget=forms.PasswordInput())
    code = forms.CharField(label='验证码', widget=forms.TextInput())

    class Meta:
        model = UserInfo
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control'
            field.widget.attrs['placeholder'] = '{}'.format(field.label, )

    def clean_username(self):
        username = self.cleaned_data['username']
        exists = models.UserInfo.objects.filter(username=username).exists()
        if exists:
            raise ValidationError('用户名已存在!')
        return username

    def clean_email(self):
        email = self.cleaned_data['email']
        exists = models.UserInfo.objects.filter(email=email).exists()
        if exists:
            raise ValidationError('邮箱已存在!')
        return email

    def clean_mobile_phone(self):
        mobile_phone = self.cleaned_data['mobile_phone']
        exists = models.UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if exists:
            raise ValidationError('手机号已存在!')
        return mobile_phone

    def clean_confirm_password(self):
        pwd = self.cleaned_data['password']
        confirm_pwd = self.cleaned_data['confirm_password']
        if confirm_pwd != pwd:
            raise ValidationError('密码不一致!')
        return confirm_pwd

    def clean_code(self):
        code = self.cleaned_data['code']
        mobile_phone = self.cleaned_data['mobile_phone']
        conn = get_redis_connection()
        redis_code = conn.get(mobile_phone)
        if not redis_code:
            raise ValidationError('请获取验证码!')
        redis_str_code = redis_code.decode('utf-8')
        if code.strip() != redis_str_code.strip():
            raise ValidationError('验证码错误, 请重新获取!')
        return code


class SendSmsForm(forms.Form):
    mobile_phone = forms.CharField(label='手机号', validators=[RegexValidator(r'^(1[3|4|5|6|7|8|9])\d{9}$', '手机号格式错误！'), ])

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request

    def clean_mobile_phone(self):
        """手机号校验钩子函数"""
        mobile_phone = self.cleaned_data['mobile_phone']

        # 判断短信模板是否存在问题
        tpl = self.request.GET.get('tpl')
        template_id = settings.TENCENT_SMS_TEMPLATE.get(tpl)
        if not template_id:
            raise ValidationError('短信模板错误！')

        # 校验手机号是否存在于数据库
        exists = UserInfo.objects.filter(mobile_phone=mobile_phone).exists()
        if exists:
            raise ValidationError('手机号已存在！')

        # 短信发送 验证码生成
        code = random.randrange(100000, 999999)  # 生成验证码
        sms_res = send_sms_single(mobile_phone, template_id, [code, 1])  # 短信发送
        if sms_res['result'] != 0:
            raise ValidationError('短信发送失败，{}'.format(sms_res['errmsg']))

        # 验证码写入redis
        conn = get_redis_connection()
        conn.set(mobile_phone, code, ex=60)

        return mobile_phone
